diff options
Diffstat (limited to 'app/[lng]')
| -rw-r--r-- | app/[lng]/evcp/(evcp)/vendors/[id]/info/rfq-history/page.tsx | 17 | ||||
| -rw-r--r-- | app/[lng]/partners/(partners)/document-upload/page.tsx | 154 |
2 files changed, 163 insertions, 8 deletions
diff --git a/app/[lng]/evcp/(evcp)/vendors/[id]/info/rfq-history/page.tsx b/app/[lng]/evcp/(evcp)/vendors/[id]/info/rfq-history/page.tsx index c7f8f8b6..6ae24f58 100644 --- a/app/[lng]/evcp/(evcp)/vendors/[id]/info/rfq-history/page.tsx +++ b/app/[lng]/evcp/(evcp)/vendors/[id]/info/rfq-history/page.tsx @@ -5,8 +5,7 @@ import { getValidFilters } from "@/lib/data-table" import { searchParamsRfqHistoryCache } from "@/lib/vendors/validations"
import { VendorRfqHistoryTable } from "@/lib/vendors/rfq-history-table/rfq-history-table"
-interface IndexPageProps {
- // Next.js 13 App Router에서 기본으로 주어지는 객체들
+interface RfqHistoryPageProps {
params: {
lng: string
id: string
@@ -14,7 +13,7 @@ interface IndexPageProps { searchParams: Promise<SearchParams>
}
-export default async function RfqHistoryPage(props: IndexPageProps) {
+export default async function RfqHistoryPage(props: RfqHistoryPageProps) {
const resolvedParams = await props.params
const lng = resolvedParams.lng
const id = resolvedParams.id
@@ -39,16 +38,18 @@ export default async function RfqHistoryPage(props: IndexPageProps) { return (
<div className="space-y-6">
<div>
- <h3 className="text-lg font-medium">
- RFQ History
- </h3>
+ <h3 className="text-lg font-medium">RFQ 견적 이력</h3>
<p className="text-sm text-muted-foreground">
- 협력업체의 RFQ 참여 이력을 확인할 수 있습니다.
+ 협력업체의 RFQ 견적 참여 이력을 확인할 수 있습니다.
</p>
</div>
<Separator />
<div>
- <VendorRfqHistoryTable promises={promises} />
+ <VendorRfqHistoryTable
+ promises={promises}
+ lng={lng}
+ vendorId={idAsNumber}
+ />
</div>
</div>
)
diff --git a/app/[lng]/partners/(partners)/document-upload/page.tsx b/app/[lng]/partners/(partners)/document-upload/page.tsx new file mode 100644 index 00000000..9df82fd4 --- /dev/null +++ b/app/[lng]/partners/(partners)/document-upload/page.tsx @@ -0,0 +1,154 @@ +// app/(vendor)/stage-submissions/page.tsx +import * as React from "react" +import { searchParamsCache } from "@/lib/vendor-document-list/plant/upload/validation" +import { StageSubmissionsTable } from "@/lib/vendor-document-list/plant/upload/table" +import { redirect } from "next/navigation" +import { + Card, + CardContent, + CardDescription, + CardHeader, + CardTitle +} from "@/components/ui/card" +import { Badge } from "@/components/ui/badge" +import { getServerSession } from 'next-auth/next' +import { authOptions } from '@/app/api/auth/[...nextauth]/route' +import { getStageSubmissions, getProjects, getSubmissionStats } from "@/lib/vendor-document-list/plant/upload/service" +import db from "@/db/db" +import { eq } from "drizzle-orm" +import { vendors } from "@/db/schema" + +export default async function StageSubmissionsPage({ + searchParams, +}: { + searchParams: Promise<Record<string, string | string[] | undefined>> +}) { + // Session 체크 + const session = await getServerSession(authOptions) + + if (!session?.user?.companyId) { + redirect("/partners") + } + + + const vendor = await db.query.vendors.findFirst({ + where: eq(vendors.id, session.user.companyId), + columns: { + vendorName: true, + vendorCode: true, + } + }) + + const params = searchParamsCache.parse(await searchParams) + + const submissionsPromise = getStageSubmissions(params) + const projectsPromise = getProjects() + const statsPromise = getSubmissionStats() + + const [submissions, projects, stats] = await Promise.all([ + submissionsPromise, + projectsPromise, + statsPromise + ]) + + return ( + <div className="container mx-auto py-6 space-y-6"> + {/* Header */} + <div className="flex items-center justify-between"> + <div> + <h1 className="text-3xl font-bold tracking-tight">My Stage Submissions</h1> + <p className="text-muted-foreground mt-1"> + Manage document submissions for your approved stages + </p> + </div> + <div className=""> + {/* <Badge variant="outline" className="gap-1"> */} + {/* <span className="font-semibold">Company:</span> */} + <span className="font-semibold"> {vendor.vendorName || "Your Company"}</span> + + <p className="text-muted-foreground text-sm"> + Buyer Approved Documents + </p> + {/* </Badge> */} + </div> + </div> + + {/* Stats Cards */} + <div className="grid gap-4 md:grid-cols-4"> + <Card> + <CardHeader className="pb-2"> + <CardDescription>Pending Submissions</CardDescription> + </CardHeader> + <CardContent> + <div className="text-2xl font-bold"> + {stats.pending} + </div> + </CardContent> + </Card> + + <Card> + <CardHeader className="pb-2"> + <CardDescription>Overdue</CardDescription> + </CardHeader> + <CardContent> + <div className="text-2xl font-bold text-destructive"> + {stats.overdue} + </div> + </CardContent> + </Card> + + <Card> + <CardHeader className="pb-2"> + <CardDescription>Awaiting Sync</CardDescription> + </CardHeader> + <CardContent> + <div className="text-2xl font-bold text-warning"> + {stats.awaitingSync} + </div> + </CardContent> + </Card> + + <Card> + <CardHeader className="pb-2"> + <CardDescription>Completed</CardDescription> + </CardHeader> + <CardContent> + <div className="text-2xl font-bold text-success"> + {stats.completed} + </div> + </CardContent> + </Card> + </div> + + {/* Main Table */} + <Card> + <CardHeader> + <CardTitle>Your Submission List</CardTitle> + <CardDescription> + View and manage document submissions for your company's stages + </CardDescription> + </CardHeader> + <CardContent> + <React.Suspense + fallback={ + <div className="flex h-[400px] items-center justify-center"> + <div className="animate-pulse text-muted-foreground"> + Loading your submissions... + </div> + </div> + } + > + <StageSubmissionsTable + promises={Promise.all([ + { data: submissions.data, pageCount: submissions.pageCount }, + { projects: projects.map(p => ({ id: p.id, code: p.code || "" })) } + ])} + selectedProjectId={params.projectId} + + /> + </React.Suspense> + </CardContent> + </Card> + </div> + ) +}
\ No newline at end of file |
